import rest_framework.throttling
from rest_framework.exceptions import APIException, ValidationError

from app01 import models
from app01.serializers import BookInfoSerializer, HeroSerializr, BookInfoModelSerializer
from rest_framework.views import APIView
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework import status, filters
from rest_framework.generics import GenericAPIView
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import action
from rest_framework.settings import settings
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import AllowAny
from rest_framework.throttling import AnonRateThrottle
from rest_framework.pagination import LimitOffsetPagination, PageNumberPagination

# class BookAPIView(APIView):
#
#     def get(self, request):
#         print(request.query_parmas)  # 获取get请求的参数
#         pass
#
#     def post(self, request):
#         print(request.data)  # 获取get和post请求的参数
#         return


# 自定义分类对象
class MyPageNumberPagination(PageNumberPagination):
    # 默认的大小
    page_size = 3
    # 前端可以指定每一页的大小
    page_size_query_param = 'page_size'
    max_page_size = 10


class BookListGenericAPIView(GenericAPIView):
    queryset = models.BookInfo.objects.all()
    serializer_class = BookInfoSerializer

    def get(self, request):
        obj = self.get_queryset()
        serializer = self.get_serializer(instance=obj, many=True)
        return Response(serializer.data)


from django_filters.rest_framework import DjangoFilterBackend


class BookInfoModelViewSet(ModelViewSet):
    queryset = models.BookInfo.objects.all()
    serializer_class = BookInfoModelSerializer
    authentication_classes = [SessionAuthentication, BasicAuthentication]
    permission_classes = _classes = [AllowAny, ]
    # throttle_classes = [AnonRateThrottle]

    # 可选限流
    # throttle_scope = 'downloads'
    throttle_scope = 'uploads'
    # pagination_class = PageNumberPagination
    pagination_class = MyPageNumberPagination

    # 局部过滤器
    # filter_backends = [DjangoFilterBackend]
    # filterset_fields = ['id', 'btitle', 'is_delete']

    # 局部排序过滤器
    # filters是rest_framework里的filters
    filter_backends = [filters.OrderingFilter]
    ordering_fields = ['id', 'btitle', 'bread']

    # 获取阅读量等于0的书籍
    @action(methods=['GET'], detail=False, url_path='bbread')
    def bbread_book(self, request):
        books = self.get_queryset().filter(bread__gte=20)
        print(books)
        serializer = self.get_serializer(instance=books, many=True)
        return Response(serializer.data)

    # 修改书籍编号为1的书籍的阅读量为99
    # partial的使用 只修改部分，传几个改几个
    @action(methods=['PUT'], detail=True)
    def update_book_bread(self, request, pk):
        book = self.get_object()
        data = request.data
        serializer = self.get_serializer(instance=book, data=data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)


# 自定义异常处理


class TestExceptionView(APIView):
    def get(self, request):
        # 只要是APIException的子类都会做处理，其错误不会
        # raise Exception('报错了')
        raise APIException('报错了')
        raise ValidationError('报错了')
        return Response()











